﻿Imports Aricie.Services
Imports Lucene.Net.Search
Imports System.Reflection
Imports Lucene.Net.Analysis

Namespace Aricie.DNN.Modules.LuceneSearch.Business
    Public Class SpecificVersionLuceneProvider
        ' singleton reference to the instantiated object 
        Private Shared objProvider As SpecificVersionLuceneProvider = Nothing

        ' constructor
        Shared Sub New()
            CreateProvider()
        End Sub

        Public Shared Function ResolveEmbeddedAssembly(senders As Object, args As ResolveEventArgs) As Assembly
            Dim resourceName As [String] = New AssemblyName(args.Name).Name + ".dll"
            For Each realResourceName As String In Assembly.GetExecutingAssembly().GetManifestResourceNames()
                If realResourceName.Contains(resourceName) Then
                    Using stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(realResourceName)
                        Dim assemblyData As [Byte]() = New [Byte](CInt(stream.Length - 1)) {}
                        stream.Read(assemblyData, 0, assemblyData.Length)
                        Return Assembly.Load(assemblyData)
                    End Using
                End If
            Next
            Return Nothing
        End Function

        ' dynamically create provider
        Private Shared Sub CreateProvider()
            Dim myLuceneInternalClass As New Lucene.Net.Support.CRC32()
            Dim luceneFrameworkVersion As String = System.Reflection.Assembly.GetAssembly(myLuceneInternalClass.GetType()).ImageRuntimeVersion
            Dim luceneFrameworkVersionObj = New Version(luceneFrameworkVersion.Replace("v", ""))

            If luceneFrameworkVersionObj.Major >= 4 Then
                Try

                    AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf ResolveEmbeddedAssembly

                    objProvider = CType(ReflectionHelper.CreateObject("Aricie.DNN.Modules.LuceneSearch.Business.LuceneNet40Provider, Aricie.LuceneSearch.Net40"), SpecificVersionLuceneProvider)

                    RemoveHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf ResolveEmbeddedAssembly

                Catch ex As Exception
                    ExceptionHelper.LogException(ex)
                    objProvider = New SpecificVersionLuceneProvider()
                End Try

            Else
                objProvider = New SpecificVersionLuceneProvider
            End If



        End Sub

        ' return the provider
        Public Shared ReadOnly Property Instance() As SpecificVersionLuceneProvider
            Get
                Return objProvider
            End Get
        End Property

        Public Overridable Function MakeStopSet(stopWords As String()) As HashSet(Of String)
            Return New HashSet(Of String)(Lucene.Net.Analysis.StopFilter.MakeStopSet(stopWords))
        End Function
        Public Overridable Function GetStopFilter(ByVal enablePositionIncrement As Boolean, ByVal stream As TokenStream, ByVal stopSet As HashSet(Of String), ByVal ignoreCase As Boolean) As StopFilter
            Return New StopFilter(enablePositionIncrement, stream, Lucene.Net.Support.Compatibility.SetFactory.CreateHashSet(Of String)(stopSet), ignoreCase)
        End Function

        Public Overridable Function CreateHashSet(Of T)() As HashSet(Of T)
            Return DirectCast(Lucene.Net.Support.Compatibility.SetFactory.CreateHashSet(Of T)(), HashSet(Of T))
        End Function
        Public Overridable Function CreateHashSet(Of T)(ByVal items As IEnumerable(Of T)) As HashSet(Of T)
            Return DirectCast(Lucene.Net.Support.Compatibility.SetFactory.CreateHashSet(Of T)(items), HashSet(Of T))
        End Function
        Public Overridable Sub ExtractNativeTerm(ByVal objQuery As Query, ByVal extractItem As HashSet(Of Lucene.Net.Index.Term))
            objQuery.ExtractTerms(DirectCast(extractItem, ISet(Of Lucene.Net.Index.Term)))
        End Sub

        Public Overridable Function GetSetBaseFieldSelectorFromHasSet(ByVal fieldsNeeded As HashSet(Of String)) As Global.Lucene.Net.Documents.SetBasedFieldSelector
            Return New Global.Lucene.Net.Documents.SetBasedFieldSelector(Lucene.Net.Support.Compatibility.SetFactory.CreateHashSet(Of String)(fieldsNeeded), Lucene.Net.Support.Compatibility.SetFactory.CreateHashSet(Of String))
        End Function

        Public Overridable Function GetStandardAnalyzer() As Lucene.Net.Analysis.Standard.StandardAnalyzer
            Return New Lucene.Net.Analysis.Standard.StandardAnalyzer(Aricie.DNN.Modules.LuceneSearch.Common.Constants.LuceneCurrentVersion, Lucene.Net.Support.Compatibility.SetFactory.CreateHashSet(Of String))

        End Function
    End Class
End Namespace